package com.yanqu.road.logic.activity.zhenhuan;

import com.yanqu.road.dao.impl.activity.zhenhuan.ZhenHuanImpl;
import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.zhenhuan.config.ZhenHuanLevelConfig;
import com.yanqu.road.entity.activity.zhenhuan.config.ZhenHuanNpcConfig;
import com.yanqu.road.entity.activity.zhenhuan.config.ZhenHuanPlaceConfig;
import com.yanqu.road.entity.activity.zhenhuan.config.ZhenHuanTextConfig;
import com.yanqu.road.entity.activity.zhenhuan.secondProcess.UserZhenHuanGoingOutData;
import com.yanqu.road.entity.config.system.NormalWeightItem;
import com.yanqu.road.logic.helper.WeightHelper;
import com.yanqu.road.pb.activity.ZhenHuanProto;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;

public class ZhenHuanSecondProcessConfig {
    private ActivityInfo activityInfo;
    private int powerCostNum;       // 消耗体力
    private int exchangeItemId;       // 兑换道具id
    private int powerGoodsId;    // 增加体力道具id
    private int initPower; // 初始体力
    private long powerRecoverCD; //恢复CD秒
    private int promotionNum; // 晋升数量
    private int partyCanJoinNum; // 茶话会可加入数量
    private int partyGoodsId; // 开启茶话会道具id
    private int joinGoodsId; // 加入茶话会道具id
    private int maxOpenNum = 20; // 同时最大开启数量
    private int openMultiPrestige = 2; // 开茶话会玩家提供倍数的共享威望
    private int dayStartHour = 18; // 每日开始时间
    private int dayEndHour = 22; // 每日结束时间
    private int recordMax = 50; // 记录最大数量
    private int multiGoingOutLimit = 10;

    private Map<Integer, ZhenHuanLevelConfig> levelConfigMap = new HashMap<>();
    private Map<Integer, ZhenHuanPlaceConfig> placeConfigMap = new HashMap<>();
    private List<NormalWeightItem> placeIdWeightList = new ArrayList<>(); // 地点权重
    private Map<Integer, ZhenHuanTextConfig> textConfigMap = new HashMap<>();
    private Map<Integer, ZhenHuanNpcConfig> npcConfigMap = new HashMap<>();

    private Map<String, ZhenHuanProto.ZhenHuanSecondProcessConfigSyncMsg> configMsgMap = new HashMap<>();

    private Random random = new Random();

    public ZhenHuanSecondProcessConfig(ActivityInfo activityInfo, Map<String, ActivityConfig> activityConfigMap) {
        this.activityInfo = activityInfo;
        this.powerCostNum = activityConfigMap.get("ZHENHUAN_2_ENERGY_CONSUME").getIntValue();
        this.exchangeItemId = activityConfigMap.get("EXCHANGE_SCORE_ITEM_ID").getIntValue();
        this.initPower = activityConfigMap.get("ZHENHUAN_2_INITIAL_ENERGY").getIntValue();
        this.powerRecoverCD = activityConfigMap.get("ZHENHUAN_2_ENERGY_RECOVER").getLongValue();
        this.promotionNum = activityConfigMap.get("ZHENHUAN_2_QUALIFICATION").getIntValue();
        this.partyCanJoinNum = activityConfigMap.get("ZHENHUAN_2_TEA_TALK_SEAT").getIntValue();
        this.partyGoodsId = activityConfigMap.get("ZHENHUAN_2_TEA_TALK_ITEM_ID").getIntValue();
        this.joinGoodsId = activityConfigMap.get("ZHENHUAN_2_TEA_INVITATION").getIntValue();
        this.powerGoodsId = activityConfigMap.get("ZHENHUAN_2_ENERGY_ITEM_ID").getIntValue();
        if (activityConfigMap.containsKey("ZHENHUAN_2_OPEN_MAX")) {
            this.maxOpenNum = activityConfigMap.get("ZHENHUAN_2_OPEN_MAX").getIntValue();
        }
        if (activityConfigMap.containsKey("ZHENHUAN_2_HOST_MULTIPLE")) {
            this.openMultiPrestige = activityConfigMap.get("ZHENHUAN_2_HOST_MULTIPLE").getIntValue();
        }
        if (activityConfigMap.containsKey("ZHENHUAN_2_RECORD_MAX")) {
            this.recordMax = activityConfigMap.get("ZHENHUAN_2_RECORD_MAX").getIntValue();
        }
        if (activityConfigMap.containsKey("ZHENHUAN_2_TEN_GACHA_UNLOCK")) {
            this.multiGoingOutLimit = activityConfigMap.get("ZHENHUAN_2_TEN_GACHA_UNLOCK").getIntValue();
        }

        if (activityConfigMap.containsKey("ZHENHUAN_2_TEA_TALK_OPEN_TIME")) {
            List<Integer> list = StringUtils.stringToIntegerList(activityConfigMap.get("ZHENHUAN_2_TEA_TALK_OPEN_TIME").getValue(), "\\|");
            if (list.size() == 2) {
                this.dayStartHour = list.get(0);
                this.dayEndHour = list.get(1);
            }
        }

        this.levelConfigMap = new ZhenHuanImpl().getGetZhenHuanLevelConfigMap(activityInfo.getActivityId());
        this.placeConfigMap = new ZhenHuanImpl().getGetZhenHuanPlaceConfigMap(activityInfo.getActivityId());
        this.textConfigMap = new ZhenHuanImpl().getGetZhenHuanTextConfigMap(activityInfo.getActivityId());
        this.npcConfigMap = new ZhenHuanImpl().getGetZhenHuanNpcConfigMap(activityInfo.getActivityId());

        for (ZhenHuanPlaceConfig placeConfig : placeConfigMap.values()) {
            this.placeIdWeightList.add(new NormalWeightItem(BigInteger.valueOf(placeConfig.getId()), placeConfig.getWeight()));
        }

    }

    public ActivityInfo getActivityInfo() {
        return activityInfo;
    }

    public int getActivityId() {
        return activityInfo.getActivityId();
    }

    public int getPowerCostNum() {
        return powerCostNum;
    }

    public int getExchangeItemId() {
        return exchangeItemId;
    }

    public int getPowerGoodsId() {
        return powerGoodsId;
    }

    public int getInitPower() {
        return initPower;
    }

    public long getPowerRecoverCD() {
        return powerRecoverCD;
    }

    public int getPromotionNum() {
        return promotionNum;
    }

    public int getPartyCanJoinNum() {
        return partyCanJoinNum;
    }

    public int getPartyGoodsId() {
        return partyGoodsId;
    }

    public ZhenHuanProto.ZhenHuanSecondProcessConfigSyncMsg getConfigMsg(String language) {
        return configMsgMap.get(language);
    }

    public void setConfigMsg(String language, ZhenHuanProto.ZhenHuanSecondProcessConfigSyncMsg configMsg) {
        configMsgMap.put(language, configMsg);
    }

    public Map<Integer, ZhenHuanLevelConfig> getLevelConfigMap() {
        return levelConfigMap;
    }

    public Map<Integer, ZhenHuanPlaceConfig> getPlaceConfigMap() {
        return placeConfigMap;
    }

    public Map<Integer, ZhenHuanTextConfig> getTextConfigMap() {
        return textConfigMap;
    }

    public Map<Integer, ZhenHuanNpcConfig> getNpcConfigMap() {
        return npcConfigMap;
    }

    public int randomPlaceId() {
        NormalWeightItem randomResult = WeightHelper.getRandomResult(placeIdWeightList);
        if (randomResult == null) {
            return 0;
        }
        return randomResult.getValue().intValue();
    }

    public ZhenHuanPlaceConfig getPlaceConfig(int placeId) {
        return placeConfigMap.get(placeId);
    }

    public ZhenHuanGoingOutResult goingOut(int num, int goingOutAmount, Map<Integer, UserZhenHuanGoingOutData> dataMap) {
        List<ZhenHuanProto.ZhenHuanSecondProcessGoingOutResultTemp> resultList = new ArrayList<>();

        Map<Integer, Integer> resultAmountMap = new HashMap<>();
        Map<Integer, Integer> resultProgressMap = new HashMap<>();
        Map<Integer, Integer> placeAddMap = new HashMap<>();//地点增加的进度
        Map<Integer, Integer> placeFullMap = new HashMap<>();//满进度的地点次数
        Property placeReward = new Property();//地点奖励
        Property fullReward = new Property();//满进度奖励

        Property totalReward = new Property();
        long totalLoveDegree = 0;

        for (UserZhenHuanGoingOutData goingOutData : dataMap.values()) {//把之前的次数和进度放进去
            resultAmountMap.put(goingOutData.getPlaceId(), goingOutData.getAmount());
            resultProgressMap.put(goingOutData.getPlaceId(), goingOutData.getProgress());
        }

        for (int i = 0; i < num; i++) {
            int placeId = randomPlaceId();

            ZhenHuanPlaceConfig placeConfig = getPlaceConfig(placeId);

            int progress = resultProgressMap.getOrDefault(placeId, 0);
            int placeAmount = resultAmountMap.getOrDefault(placeId, 0);

            progress++;
            placeAmount++;

            Property reward = PropertyHelper.randomPropertyByListList(placeConfig.getReachRewardList());

            placeAddMap.put(placeId, placeAddMap.getOrDefault(placeId, 0) + 1);
            placeReward.addProperty(reward);

            Property overReward = new Property();
            long addLoveDegree = placeConfig.getLoveReward();

            if (progress >= placeConfig.getProgress()) { //进度满获得特殊奖励
                progress = 0;
                overReward = placeConfig.getOverRewardProperty();

                placeFullMap.put(placeId, placeFullMap.getOrDefault(placeId, 0) + 1);
                fullReward.addProperty(overReward);
            }

            resultAmountMap.put(placeId, placeAmount);
            resultProgressMap.put(placeId, progress);
            totalReward.addProperty(reward);
            totalReward.addProperty(overReward);
            totalLoveDegree += addLoveDegree;

            goingOutAmount++;

            ZhenHuanProto.ZhenHuanSecondProcessGoingOutResultTemp.Builder builder = ZhenHuanProto.ZhenHuanSecondProcessGoingOutResultTemp.newBuilder();
            builder.setPlaceId(placeId);
            builder.setProgress(progress);
            builder.setAmount(placeAmount);
            builder.setReward(reward.toHelperString());
            builder.setOverReward(overReward.toHelperString());
            builder.setGoingOutAmount(goingOutAmount);
            builder.setAddLoveDegree(addLoveDegree);
            resultList.add(builder.build());
        }

        ZhenHuanGoingOutResult zhenHuanGoingOutResult = new ZhenHuanGoingOutResult(resultList, totalReward, resultProgressMap, resultAmountMap, goingOutAmount, totalLoveDegree);
        zhenHuanGoingOutResult.setPlaceAddMap(placeAddMap);
        zhenHuanGoingOutResult.setPlaceFullMap(placeFullMap);
        zhenHuanGoingOutResult.setPlaceReward(placeReward.toHelperString());
        zhenHuanGoingOutResult.setFullReward(fullReward.toHelperString());

        return zhenHuanGoingOutResult;
    }

    public ZhenHuanLevelConfig getLevelConfig(int level) {
        return levelConfigMap.get(level);
    }

    public int getMaxLevel() {
        return levelConfigMap.size();
    }

    /**
     * 开宴会时的结算时间
     *
     * @param openTime
     * @return
     */
    public long calcPartyEndTime(int level, long openTime) {
        long endTime = openTime + 300 * DateHelper.SECOND_MILLIONS;
        ZhenHuanLevelConfig levelConfig = getLevelConfig(level);
        if (levelConfig != null) {
            endTime = openTime + levelConfig.getPartyTime() * DateHelper.SECOND_MILLIONS;
        }
        long todayZeroTimeStamp = DateHelper.getTodayZeroTimeStamp();
        long dayEndTime = todayZeroTimeStamp + dayEndHour * DateHelper.HOUR_MILLIONS;
        if (endTime > dayEndTime) {
            endTime = dayEndTime;
        }

        return endTime;
    }

    public long calcPartyKickEndTime(int level) {
        long endTime = DateHelper.getCurrentTime() + 300 * DateHelper.SECOND_MILLIONS;
        ZhenHuanLevelConfig levelConfig = getLevelConfig(level);
        if (levelConfig != null) {
            endTime = DateHelper.getCurrentTime() + levelConfig.getCompeteTime() * DateHelper.SECOND_MILLIONS;
        }
        long todayZeroTimeStamp = DateHelper.getTodayZeroTimeStamp();
        long dayEndTime = todayZeroTimeStamp + dayEndHour * DateHelper.HOUR_MILLIONS;
        if (endTime > dayEndTime) {
            endTime = dayEndTime;
        }

        return endTime;
    }

    public String parsePrestigeRewardString(long prestigeDegree) {
        Property reward = new Property(exchangeItemId, prestigeDegree);
        return reward.toHelperString();
    }

    public int getJoinGoodsId() {
        return joinGoodsId;
    }

    public Property getKickBackReward() {
        return new Property(joinGoodsId, 1);
    }

    public int getMaxOpenNum() {
        return maxOpenNum;
    }

    public int getOpenMultiPrestige() {
        return openMultiPrestige;
    }

    public List<ZhenHuanNpcConfig> randomNpcList() {
        List<ZhenHuanNpcConfig> npcList = new ArrayList<>();
        npcList.addAll(npcConfigMap.values());

        Collections.shuffle(npcList);
        return npcList;
    }

    public boolean isNpc(long npcId) {
        return npcConfigMap.containsKey((int)npcId);
    }

    public boolean isInDayOptionTime() {
        long todayZeroTimeStamp = DateHelper.getTodayZeroTimeStamp();
        long now = DateHelper.getCurrentTime();
        long dayStartTime = todayZeroTimeStamp + dayStartHour * DateHelper.HOUR_MILLIONS;
        long dayEndTime = todayZeroTimeStamp + dayEndHour * DateHelper.HOUR_MILLIONS;
        return now >= dayStartTime && now < dayEndTime;
    }

    public int getRecordMax() {
        return recordMax;
    }

    public int getMultiGoingOutLimit() {
        return multiGoingOutLimit;
    }
}